package com.miyake.dsp.osa.method;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang.ArrayUtils;

import com.miyake.dsp.ComplexArray;
import com.miyake.dsp.ScilabExecute;
import com.miyake.dsp.common.UnitConverter;
import com.miyake.dsp.osa.AnalysisProperty;
import com.miyake.dsp.osa.lab.Fitting2;

public class SpectDivOn implements NFCalc  {
	private double ase;
	private double gain;

	private List<double[]> traces = new ArrayList<double[]>();
	private double[] subX;
	private double fittingStart;
	private double fittingEnd;
	private double maskedStart;
	private double maskedEnd;

	/* (non-Javadoc)
	 * @see com.miyake.dsp.osa.NFCalc#setData(double[], double[], double[], com.miyake.dsp.fitting.FittingSetting)
	 */
	@Override
	public void setData(double[] x, double[] in, double[] out,
			AnalysisProperty setting, boolean fitInLog,
			int peakIndex, int outPeakIndex, int peakCenterIndex, double center) {

		traces.clear();
		this.fittingStart = setting.getFittingStart();
		this.fittingEnd = setting.getFittingEnd();
		this.maskedStart = center - setting.getMaskedSpan()/2.0;
		this.maskedEnd = center + setting.getMaskedSpan()/2.0;

		Extractor extractor = new Extractor(x);

		if (setting.isPoint()) {
			extractor.setPoint(setting.getFittingStart(), setting.getFittingEnd());
		}
		else {
			extractor.setArea(setting.getFittingStart(), setting.getFittingEnd(), this.maskedStart, this.maskedEnd);
		}
		subX = extractor.getBaseToBeFilled();

		Fitting2 fitting = new Fitting2(setting.getFormula());
		double tmpgain = out[peakIndex] / in[peakIndex];

		double[] corr = ScilabExecute.execute("ret=data1 - data2*" + String.valueOf(tmpgain),
				new ComplexArray(out), new ComplexArray(in), "ret").getRealPart();

		extractor.addData(corr, "Corr");
		NormalizeX nx = new NormalizeX(extractor.getFittingDataX(), subX);

		if (fitInLog) {
			fitting.setOriginalData(nx.getNomalizedOriginal(), UnitConverter.todBm(extractor.getFittingData("Corr")));
		}
		else {
			fitting.setOriginalData(nx.getNomalizedOriginal(), extractor.getFittingData("Corr"));
		}
		double[] fit = fitting.getInterpolated(nx.getNomalizedInterpolate());
		if (fitInLog) {
			fit = UnitConverter.toW(fit);
		}
		traces.add(ArrayUtils.subarray(corr, extractor.getiStart(), extractor.getiEnd()+1));
		traces.add(fit);

		Double inPeak = in[peakIndex];
		Double outPeak = out[peakIndex];
		ase = fit[peakIndex - extractor.getiStart()];
		gain = (outPeak - ase) / inPeak;
	}

	/* (non-Javadoc)
	 * @see com.miyake.dsp.osa.NFCalc#getNF()
	 */
	@Override
	public double getAse() {
		return ase;
	}

	/* (non-Javadoc)
	 * @see com.miyake.dsp.osa.NFCalc#getGain()
	 */
	@Override
	public double getGain() {
		return gain;
	}

	/* (non-Javadoc)
	 * @see com.miyake.dsp.osa.NFCalc#getTraces()
	 */
	@Override
	public List<double[]> getTraces() {
		return traces;
	}

	@Override
	public double[] getSubX() {
		return this.subX;
	}

	@Override
	public Double getFittingStart() {
		return this.fittingStart;
	}

	@Override
	public Double getFittingEnd() {
		return this.fittingEnd;
	}

	@Override
	public Double getMaskedStart() {
		return this.maskedStart;
	}

	@Override
	public Double getMaskedEnd() {
		return this.maskedEnd;
	}


}
